<?php

namespace app\components;

use api\utils\LogUtil;
use Yii;

class Job
{
    public $redis;

    const DEFAULT_QUEUE = 'redis_paidan30_job_queue';
    const REDIS_QUEUES_KEY = 'redis_paidan30_queues';

    public function __construct()
    {
        $this->redis = Yii::$app->jobRedis;
    }

    public function create($class, $args, $queue = self::DEFAULT_QUEUE)
    {
        try {
            if (empty($class)) {
                return false;
            }
            $job = [
                'jobId' => self::generateJobId(),
                'class' => $class,
                'args' => $args,
                'enqueueAt' => microtime(true),
            ];
            if (empty($params['executeAt'])) {
                $this->pushQueue($job, $queue);
                return $job;
            }
            // TODO: 延迟执行
            $this->pushDelayQueue($job, $queue);
        } catch (\Exception $e) {
            LogUtil::warn('Component-Job: create job error ' . $e->getMessage() . ' job: ' . json_encode($job));
        }
    }

    /*
	 * Generate an identifier to attach to a job for status tracking.
	 *
	 * @return string
	 */
	public static function generateJobId()
	{
		return md5(uniqid('', true));
    }

    /**
     * @param array job data
     * @param string queue
     */
    public function pushQueue($job, $queue)
    {
        $redis = $this->redis;
        $redis->sadd(self::REDIS_QUEUES_KEY, $queue);
        $length = $redis->rpush($queue, json_encode($job));
        if ($length < 1) {
            return false;
        }

        return true;
    }

    public function pop($queue)
    {
        $item = $this->redis->lpop($queue);
        if (empty($item)) {
            return;
        }

        $instance = $this->getInstance(json_decode($item, true));
        if (empty($instance)) {
            LogUtil::warn('create job instance failed');
        }
        return $instance;
    }

    public function getInstance($item)
    {
        if (!class_exists($item['class'])) {
            LogUtil::warn('create job instance class not exists' . $item['class']);
            return false;
        }
        $job = new $item['class']($item['args'], $item['jobId']);

        return $job;
    }

    public function pushDelayQueue($job, $queue)
    {

    }
}
